/* Copyright (C) 2008, 2009, 2010 Faindu GmbH, Switzerland.
* All Rights Reserved. The following is Source Code and is subject to all restrictions 
* on such code as contained in the license accompanying this project. */
package blocstac.editimage.scale
{

import blocstac.editimage.base.Control;
import blocstac.editimage.base.ImageOperation;
import blocstac.editimage.base.StateManager;
import blocstac.editimage.base.ViewModel;

import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;

/**
 * The user drags these "buttons" to edit the image.
 */
public class ScaleTool extends Control
{
	
	function ScaleTool(stateManager:StateManager, imageComponent:Bitmap) {
		super(stateManager)
		_imageComponent = imageComponent
	}
	
	//--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
	private static const SIZE:Number = 16 
	private static const HALF_SIZE:Number = SIZE/2;
	private var _imageComponent:Bitmap
	private var _scaleInit:ScaleInit
	private var _stageToImageComponent:Matrix
	private var _operation:ImageOperation
	
	/** @inheritDoc */
	override protected function draw(event:Event=null): void 
	{
		super.draw()
		
		graphics.clear()
		graphics.lineStyle(1, 0xf8f8f8)
		graphics.beginFill(0x222222)
		
		graphics.drawRect(-SIZE+2, -SIZE+2, SIZE, SIZE)
		graphics.endFill()
	}

	//--------------------------------------------------------------------------
	//
	//  Methods
	//
	//--------------------------------------------------------------------------
	override public function init(toolPlane:Sprite): void {
		cursor = new ScaleCursor()
		update()
		addEventListener(MouseEvent.CLICK, clickCanceler)
		
		super.init(toolPlane)
	}
	
	private function clickCanceler(event:MouseEvent):void {
		event.stopImmediatePropagation()
	}
	
	override protected function startInteractionHandler(mouseEvent:MouseEvent):void {
		if (stateManager.interactionStarts()) {
			var viewModel:ViewModel = stateManager.viewModel
			_scaleInit = new ScaleInit()
			_scaleInit.editedScaleX = viewModel.editedScaleX
			_scaleInit.editedScaleY = viewModel.editedScaleY
			_scaleInit.brImageCornerInRotationCompUnscaled = viewModel.brImageCornerInRotationCompUnscaled
			var imageCompToStage:Matrix = _imageComponent.transform.concatenatedMatrix
			_stageToImageComponent = imageCompToStage.clone()
			_stageToImageComponent.invert()
			
			var brImageCornerOnStage:Point = imageCompToStage.transformPoint(viewModel.brImageCornerInRotationCompUnscaled)
			_scaleInit.mouseToImageCornerOffsetUnscaled = new Point(mouseEvent.stageX - brImageCornerOnStage.x, mouseEvent.stageY - brImageCornerOnStage.y)
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE, interaction)
			stage.addEventListener(MouseEvent.MOUSE_UP, endInteractionHandler)
			stage.addEventListener(Event.MOUSE_LEAVE, endInteractionOutsideHandler)
		}
	}
	
	private function interaction(mouseEvent:MouseEvent):void {
		_operation = createOp(mouseEvent.stageX, mouseEvent.stageY, mouseEvent.shiftKey, _scaleInit)
		stateManager.apply(_operation)
	}
	
	private function endInteractionOutsideHandler(event:Event):void {
		endInteraction(_operation)
	}
	
	private function endInteractionHandler(mouseEvent:MouseEvent):void {
		var op:ImageOperation = createOp(mouseEvent.stageX, mouseEvent.stageY, mouseEvent.shiftKey, _scaleInit)
		endInteraction(op)
	}
	
	private function endInteraction(scaleOperation:ImageOperation):void {
		if (stage) {
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, interaction)
			stage.removeEventListener(MouseEvent.MOUSE_UP, endInteractionHandler)
			stage.removeEventListener(Event.MOUSE_LEAVE, endInteractionOutsideHandler)
		}
		
		stateManager.interactionEnds(scaleOperation)
		
		_scaleInit = null
	}
	
	internal function createOp(mouseStageX:Number, mouseStageY:Number, shiftKey:Boolean, _scaleInit:ScaleInit):ImageOperation {
		var mouseLocationOnStage:Point = new Point(mouseStageX, mouseStageY)
		var mouseLocationInUnscaledImageComp:Point = _stageToImageComponent.transformPoint(mouseLocationOnStage)
		return new ScaleOperation(_scaleInit, mouseLocationInUnscaledImageComp, ! shiftKey)
	}
	
	public function update():void {
		var viewModel:ViewModel = stateManager.viewModel
		x = viewModel.imageViewWidth
		y = viewModel.imageViewHeight
	}
	
}
}